dojo.require("dojo.NodeList-manipulate");
dojo.require('dojo.NodeList-fx');

var dTableSorter = (function() {
	var $d = dojo, $ = $d.query, 
	col = {
		NUMBER : 1,
		STRING : 2
	},
	contentNode,	
	colorEvenRows = function() {    
	    //$('#content tr:nth-child(even)').addClass('dTableSorter-row-even');
		$(contentNode.get('tr')).forEach(function(el, i) {
		    $d.removeClass(el,'dTableSorter-row-even');                        
			if (i % 2 === 0) {
			    $d.addClass(el,'dTableSorter-row-even');              
  		    }          
		});
	},
	deleteRows = function() {
		var nodes = $('.dTableSorter-row-selected');
		nodes.fadeOut({
			duration:800,
			onEnd:function() {
				nodes.remove();
				colorEvenRows();
			}
		}).play();        
	};
	
	var Columns = (function() {   		
		var fn = function(colType) {	
			switch(colType) {		
				case col.STRING : {
					return function(isSorted, a, b) {
						return isSorted ? 
						   (b > a ? 1 : a === b ? 0 : -1) : (b < a ? 1 : a === b ? 0 : -1);
					}
				}		
				case col.NUMBER :
				default : {
					return function(isSorted, a, b) {
						return isSorted ? (b - a) : (a - b);
					}
				}
			}
		};	
		return {		
			setColumns : function(columns) {
				this.sortableColumns = columns;
			},			
			getSortFunction : function(el) {
				var colName = typeof el === 'string' ? el : el.id,
					s = this.sortableColumns || {};
				if (typeof s[colName] === 'undefined') {
					throw new Error('No such column name: '+ colName);
				}
				return fn(s[colName]);
			},			
			toString : function() {
				var a = [];
				for (var key in this.sortableColumns) {
					a.push(['#', key].join(''));
				}
				return a.join(', ');
			}
		};
	})();

	var ContentNodeQuery = function(node) {
		this.node = ['#', node].join('');
		this.get = function(query) {
			if (!query) {
				//console.log(this.node);
				return this.node;
			}		
			//console.log([this.node, ' ', query].join(''));
			return [this.node, ' ', query].join('');
		};
	},

	init = function(properties) {           	
		Columns.setColumns(properties.columns);
		if (!$d.byId(properties.table)) {
			throw new Error('No table with id : ' + properties.table);
		}						
		
		var q = contentNode = new ContentNodeQuery(properties.table);
		
		colorEvenRows();
		$(q.get('tbody tr')).onclick(function(el) {         
			if ($d.hasClass(this,'dTableSorter-row-selected')) {
				$d.removeClass(this,'dTableSorter-row-selected');              
			} else {
				$d.addClass(this,'dTableSorter-row-selected');
			}
		})
		.onmouseover(function(e) {
			$d.style(this, 'color','#36F');
		})                  
		.onmouseout(function() {
			$d.style(this, 'color','#000');
		})                  
		.style('cursor', 'pointer');                  
	
		$(Columns.toString())      
			.addClass('dTableSorter-header-col')
			.onmouseover(function() { $d.style(this, 'textDecoration','underline'); })
			.onmouseout(function() { $d.style(this, 'textDecoration','none'); })
			.style('cursor','pointer').forEach(function(el, index) {          
				$d.connect(el, 'click', function() {           
				$('.dTableSorter-header-col-choosen').removeClass('dTableSorter-header-col-choosen');
				$d.addClass(el,'dTableSorter-header-col-choosen');
				var isSorted = !$d.hasClass(el,'dTableSorter-sorted');            
				if (isSorted) {
					$d.addClass(el,'dTableSorter-sorted');
				} else {
					$d.removeClass(el,'dTableSorter-sorted');
				}
				
				var sortFunction = Columns.getSortFunction(el),
					sorted = $d.map($(q.get('tbody tr td:nth-child('+(index+1)+')')).sort(function(e1, e2) {
						var a = $(e1).text(), b = $(e2).text();
						return sortFunction(isSorted, a, b);               
					}), function(el) { return el.parentNode; });
					
			   $(q.get('tbody tr')).remove();
			   $(q.get('tbody')).append(sorted); 
			   colorEvenRows();
		   });      
	   });     
	};
	return { 
		init : init,
		removeSelected : deleteRows
	};
})();
	
 
